home *** CD-ROM | disk | FTP | other *** search
/ Space & Astronomy / Space and Astronomy (October 1993).iso / mac / VIEWERS / MSDOS / GIFLIB12.ZIP / LIB / DGIF_LIB.C < prev    next >
C/C++ Source or Header  |  1991-08-05  |  30KB  |  838 lines

  1. /******************************************************************************
  2. *   "Gif-Lib" - Yet another gif library.                      *
  3. *                                          *
  4. * Written by:  Gershon Elber            IBM PC Ver 1.1,    Aug. 1990     *
  5. *******************************************************************************
  6. * The kernel of the GIF Decoding process can be found here.              *
  7. *******************************************************************************
  8. * History:                                      *
  9. * 16 Jun 89 - Version 1.0 by Gershon Elber.                      *
  10. *  3 Sep 90 - Version 1.1 by Gershon Elber (Support for Gif89, Unique names). *
  11. ******************************************************************************/
  12.  
  13.  
  14. #ifdef __MSDOS__
  15. #include <io.h>
  16. #include <alloc.h>
  17. #include <stdlib.h>
  18. #include <sys\stat.h>
  19. #else
  20. #include <sys/types.h>
  21. #include <sys/stat.h>
  22. #endif /* __MSDOS__ */
  23.  
  24. #include <fcntl.h>
  25. #include <stdio.h>
  26. #include <string.h>
  27. #include "gif_lib.h"
  28. #include "gif_hash.h"
  29.  
  30. #define PROGRAM_NAME    "GIF_LIBRARY"
  31.  
  32. #define COMMENT_EXT_FUNC_CODE    0xfe /* Extension function code for comment. */
  33. #define GIF_STAMP    "GIFVER"     /* First chars in file - GIF stamp. */
  34. #define GIF_STAMP_LEN    sizeof(GIF_STAMP) - 1
  35. #define GIF_VERSION_POS    3        /* Version first character in stamp. */
  36.  
  37. #define LZ_MAX_CODE    4095        /* Biggest code possible in 12 bits. */
  38. #define LZ_BITS        12
  39.  
  40. #define FILE_STATE_READ        0x01/* 1 write, 0 read - EGIF_LIB compatible.*/
  41.  
  42. #define FLUSH_OUTPUT        4096    /* Impossible code, to signal flush. */
  43. #define FIRST_CODE        4097    /* Impossible code, to signal first. */
  44. #define NO_SUCH_CODE        4098    /* Impossible code, to signal empty. */
  45.  
  46. #define IS_READABLE(Private)    (!(Private -> FileState & FILE_STATE_READ))
  47.  
  48. typedef struct GifFilePrivateType {
  49.     int FileState,
  50.     FileHandle,                 /* Where all this data goes to! */
  51.     BitsPerPixel,        /* Bits per pixel (Codes uses at list this + 1). */
  52.     ClearCode,                       /* The CLEAR LZ code. */
  53.     EOFCode,                         /* The EOF LZ code. */
  54.     RunningCode,            /* The next code algorithm can generate. */
  55.     RunningBits,/* The number of bits required to represent RunningCode. */
  56.     MaxCode1,  /* 1 bigger than max. possible code, in RunningBits bits. */
  57.     LastCode,                /* The code before the current code. */
  58.     CrntCode,                  /* Current algorithm code. */
  59.     StackPtr,                 /* For character stack (see below). */
  60.     CrntShiftState;                /* Number of bits in CrntShiftDWord. */
  61.     unsigned long CrntShiftDWord,     /* For bytes decomposition into codes. */
  62.           PixelCount;               /* Number of pixels in image. */
  63.     FILE *File;                          /* File as stream. */
  64.     GifByteType Buf[256];           /* Compressed input is buffered here. */
  65.     GifByteType Stack[LZ_MAX_CODE];     /* Decoded pixels are stacked here. */
  66.     GifByteType Suffix[LZ_MAX_CODE+1];           /* So we can trace the codes. */
  67.     unsigned int Prefix[LZ_MAX_CODE+1];
  68. } GifFilePrivateType;
  69.  
  70. #ifdef SYSV
  71. static char *VersionStr =
  72.         "Gif library module,\t\tGershon Elber\n\
  73.     (C) Copyright 1989 Gershon Elber, Non commercial use only.\n";
  74. #else
  75. static char *VersionStr =
  76.     PROGRAM_NAME
  77.     "    IBMPC "
  78.     GIF_LIB_VERSION
  79.     "    Gershon Elber,    "
  80.     __DATE__ ",   " __TIME__ "\n"
  81.     "(C) Copyright 1989 Gershon Elber, Non commercial use only.\n";
  82. #endif /* SYSV */
  83.  
  84. extern int _GifError;
  85.  
  86. static int DGifGetWord(FILE *File, int *Word);
  87. static int DGifSetupDecompress(GifFileType *GifFile);
  88. static int DGifDecompressLine(GifFileType *GifFile, GifPixelType *Line,
  89.                                 int LineLen);
  90. static int DGifGetPrefixChar(unsigned int *Prefix, int Code, int ClearCode);
  91. static int DGifDecompressInput(GifFilePrivateType *Private, int *Code);
  92. static int DGifBufferedInput(FILE *File, GifByteType *Buf,
  93.                              GifByteType *NextByte);
  94.  
  95. /******************************************************************************
  96. *   Open a new gif file for read, given by its name.                  *
  97. *   Returns GifFileType pointer dynamically allocated which serves as the gif *
  98. * info record. _GifError is cleared if succesfull.                  *
  99. ******************************************************************************/
  100. GifFileType *DGifOpenFileName(char *FileName)
  101. {
  102.     int FileHandle;
  103.  
  104.     if ((FileHandle = open(FileName, O_RDONLY
  105. #ifdef __MSDOS__
  106.                        | O_BINARY
  107. #endif /* __MSDOS__ */
  108.                                  )) == -1) {
  109.     _GifError = D_GIF_ERR_OPEN_FAILED;
  110.     return NULL;
  111.     }
  112.  
  113.     return DGifOpenFileHandle(FileHandle);
  114. }
  115.  
  116. /******************************************************************************
  117. *   Update a new gif file, given its file handle.                  *
  118. *   Returns GifFileType pointer dynamically allocated which serves as the gif *
  119. * info record. _GifError is cleared if succesfull.                  *
  120. ******************************************************************************/
  121. GifFileType *DGifOpenFileHandle(int FileHandle)
  122. {
  123.     char Buf[GIF_STAMP_LEN+1];
  124.     GifFileType *GifFile;
  125.     GifFilePrivateType *Private;
  126.     FILE *f;
  127.  
  128. #ifdef __MSDOS__
  129.     setmode(FileHandle, O_BINARY);      /* Make sure it is in binary mode. */
  130.     f = fdopen(FileHandle, "rb");           /* Make it into a stream: */
  131.     setvbuf(f, NULL, _IOFBF, GIF_FILE_BUFFER_SIZE);/* And inc. stream buffer.*/
  132. #else
  133.     f = fdopen(FileHandle, "r");           /* Make it into a stream: */
  134. #endif /* __MSDOS__ */
  135.  
  136.     if ((GifFile = (GifFileType *) malloc(sizeof(GifFileType))) == NULL) {
  137.     _GifError = D_GIF_ERR_NOT_ENOUGH_MEM;
  138.     return NULL;
  139.     }
  140.  
  141.     if ((Private = (GifFilePrivateType *) malloc(sizeof(GifFilePrivateType)))
  142.     == NULL) {
  143.     _GifError = D_GIF_ERR_NOT_ENOUGH_MEM;
  144.     free((char *) GifFile);
  145.     return NULL;
  146.     }
  147.     GifFile -> Private = (VoidPtr) Private;
  148.     GifFile -> SColorMap = GifFile -> IColorMap = NULL;
  149.     Private -> FileHandle = FileHandle;
  150.     Private -> File = f;
  151.     Private -> FileState = 0;   /* Make sure bit 0 = 0 (File open for read). */
  152.  
  153.     /* Lets see if this is GIF file: */
  154.     if (fread(Buf, 1, GIF_STAMP_LEN, Private -> File) != GIF_STAMP_LEN) {
  155.     _GifError = D_GIF_ERR_READ_FAILED;
  156.     free((char *) Private);
  157.     free((char *) GifFile);
  158.     return NULL;
  159.     }
  160.  
  161.     /* The GIF Version number is ignored at this time. Maybe we should do    */
  162.     /* something more useful with it.                         */
  163.     Buf[GIF_STAMP_LEN] = 0;
  164.     if (strncmp(GIF_STAMP, Buf, GIF_VERSION_POS) != 0) {
  165.     _GifError = D_GIF_ERR_NOT_GIF_FILE;
  166.     free((char *) Private);
  167.     free((char *) GifFile);
  168.     return NULL;
  169.     }
  170.  
  171.     if (DGifGetScreenDesc(GifFile) == GIF_ERROR) {
  172.     free((char *) Private);
  173.     free((char *) GifFile);
  174.     return NULL;
  175.     }
  176.  
  177.     _GifError = 0;
  178.  
  179.     return GifFile;
  180. }
  181.  
  182. /******************************************************************************
  183. *   This routine should be called before any other DGif calls. Note that      *
  184. * this routine is called automatically from DGif file open routines.          *
  185. ******************************************************************************/
  186. int DGifGetScreenDesc(GifFileType *GifFile)
  187. {
  188.     int Size, i;
  189.     GifByteType Buf[3];
  190.     GifFilePrivateType *Private = (GifFilePrivateType *) GifFile -> Private;
  191.  
  192.     if (!IS_READABLE(Private)) {
  193.     /* This file was NOT open for reading: */
  194.     _GifError = D_GIF_ERR_NOT_READABLE;
  195.     return GIF_ERROR;
  196.     }
  197.  
  198.     /* Put the screen descriptor into the file: */
  199.     if (DGifGetWord(Private -> File, &GifFile -> SWidth) == GIF_ERROR ||
  200.     DGifGetWord(Private -> File, &GifFile -> SHeight) == GIF_ERROR)
  201.     return GIF_ERROR;
  202.  
  203.     if (fread(Buf, 1, 3, Private -> File) != 3) {
  204.     _GifError = D_GIF_ERR_READ_FAILED;
  205.     return GIF_ERROR;
  206.     }
  207.     GifFile -> SColorResolution = (((Buf[0] & 0x70) + 1) >> 4) + 1;
  208.     GifFile -> SBitsPerPixel = (Buf[0] & 0x07) + 1;
  209.     GifFile -> SBackGroundColor = Buf[1];
  210.     if (Buf[0] & 0x80) {             /* Do we have global color map? */
  211.     Size = (1 << GifFile -> SBitsPerPixel);
  212.     GifFile -> SColorMap =
  213.         (GifColorType *) malloc(sizeof(GifColorType) * Size);
  214.     for (i = 0; i < Size; i++) {        /* Get the global color map: */
  215.         if (fread(Buf, 1, 3, Private -> File) != 3) {
  216.         _GifError = D_GIF_ERR_READ_FAILED;
  217.         return GIF_ERROR;
  218.         }
  219.         GifFile -> SColorMap[i].Red = Buf[0];
  220.         GifFile -> SColorMap[i].Green = Buf[1];
  221.         GifFile -> SColorMap[i].Blue = Buf[2];
  222.     }
  223.     }
  224.  
  225.     return GIF_OK;
  226. }
  227.  
  228. /******************************************************************************
  229. *   This routine should be called before any attemp to read an image.         *
  230. ******************************************************************************/
  231. int DGifGetRecordType(GifFileType *GifFile, GifRecordType *Type)
  232. {
  233.     GifByteType Buf;
  234.     GifFilePrivateType *Private = (GifFilePrivateType *) GifFile -> Private;
  235.  
  236.     if (!IS_READABLE(Private)) {
  237.     /* This file was NOT open for reading: */
  238.     _GifError = D_GIF_ERR_NOT_READABLE;
  239.     return GIF_ERROR;
  240.     }
  241.  
  242.     if (fread(&Buf, 1, 1, Private -> File) != 1) {
  243.     _GifError = D_GIF_ERR_READ_FAILED;
  244.     return GIF_ERROR;
  245.     }
  246.  
  247.     switch (Buf) {
  248.     case ',':
  249.         *Type = IMAGE_DESC_RECORD_TYPE;
  250.         break;
  251.     case '!':
  252.         *Type = EXTENSION_RECORD_TYPE;
  253.         break;
  254.     case ';':
  255.         *Type = TERMINATE_RECORD_TYPE;
  256.         break;
  257.     default:
  258.         *Type = UNDEFINED_RECORD_TYPE;
  259.         _GifError = D_GIF_ERR_WRONG_RECORD;
  260.         return GIF_ERROR;
  261.     }
  262.  
  263.     return GIF_OK;
  264. }
  265.  
  266. /******************************************************************************
  267. *   This routine should be called before any attemp to read an image.         *
  268. *   Note it is assumed the Image desc. header (',') has been read.          *
  269. ******************************************************************************/
  270. int DGifGetImageDesc(GifFileType *GifFile)
  271. {
  272.     int Size, i;
  273.     GifByteType Buf[3];
  274.     GifFilePrivateType *Private = (GifFilePrivateType *) GifFile -> Private;
  275.  
  276.     if (!IS_READABLE(Private)) {
  277.     /* This file was NOT open for reading: */
  278.     _GifError = D_GIF_ERR_NOT_READABLE;
  279.     return GIF_ERROR;
  280.     }
  281.  
  282.     if (DGifGetWord(Private -> File, &GifFile -> ILeft) == GIF_ERROR ||
  283.     DGifGetWord(Private -> File, &GifFile -> ITop) == GIF_ERROR ||
  284.     DGifGetWord(Private -> File, &GifFile -> IWidth) == GIF_ERROR ||
  285.     DGifGetWord(Private -> File, &GifFile -> IHeight) == GIF_ERROR)
  286.     return GIF_ERROR;
  287.     if (fread(Buf, 1, 1, Private -> File) != 1) {
  288.     _GifError = D_GIF_ERR_READ_FAILED;
  289.     return GIF_ERROR;
  290.     }
  291.     GifFile -> IBitsPerPixel = (Buf[0] & 0x07) + 1;
  292.     GifFile -> IInterlace = (Buf[0] & 0x40);
  293.     if (Buf[0] & 0x80) {        /* Does this image have local color map? */
  294.     Size = (1 << GifFile -> IBitsPerPixel);
  295.     if (GifFile -> IColorMap) free((char *) GifFile -> IColorMap);
  296.     GifFile -> IColorMap =
  297.         (GifColorType *) malloc(sizeof(GifColorType) * Size);
  298.     for (i = 0; i < Size; i++) {       /* Get the image local color map: */
  299.         if (fread(Buf, 1, 3, Private -> File) != 3) {
  300.         _GifError = D_GIF_ERR_READ_FAILED;
  301.         return GIF_ERROR;
  302.         }
  303.         GifFile -> IColorMap[i].Red = Buf[0];
  304.         GifFile -> IColorMap[i].Green = Buf[1];
  305.         GifFile -> IColorMap[i].Blue = Buf[2];
  306.     }
  307.     }
  308.  
  309.     Private -> PixelCount = (long) GifFile -> IWidth *
  310.                 (long) GifFile -> IHeight;
  311.  
  312.     DGifSetupDecompress(GifFile);  /* Reset decompress algorithm parameters. */
  313.  
  314.     return GIF_OK;
  315. }
  316.  
  317. /******************************************************************************
  318. *  Get one full scanned line (Line) of length LineLen from GIF file.          *
  319. ******************************************************************************/
  320. int DGifGetLine(GifFileType *GifFile, GifPixelType *Line, int LineLen)
  321. {
  322.     GifByteType *Dummy;
  323.     GifFilePrivateType *Private = (GifFilePrivateType *) GifFile -> Private;
  324.  
  325.     if (!IS_READABLE(Private)) {
  326.     /* This file was NOT open for reading: */
  327.     _GifError = D_GIF_ERR_NOT_READABLE;
  328.     return GIF_ERROR;
  329.     }
  330.  
  331.     if (!LineLen) LineLen = GifFile -> IWidth;
  332.  
  333. #ifdef __MSDOS__
  334.     if ((Private -> PixelCount -= LineLen) > 0xffff0000UL) {
  335. #else
  336.     if ((Private -> PixelCount -= LineLen) > 0xffff0000) {
  337. #endif /* __MSDOS__ */
  338.     _GifError = D_GIF_ERR_DATA_TOO_BIG;
  339.     return GIF_ERROR;
  340.     }
  341.  
  342.     if (DGifDecompressLine(GifFile, Line, LineLen) == GIF_OK) {
  343.     if (Private -> PixelCount == 0) {
  344.         /* We probably would not be called any more, so lets clean          */
  345.         /* everything before we return: need to flush out all rest of    */
  346.         /* image until empty block (size 0) detected. We use GetCodeNext.*/
  347.         do if (DGifGetCodeNext(GifFile, &Dummy) == GIF_ERROR)
  348.         return GIF_ERROR;
  349.         while (Dummy != NULL);
  350.     }
  351.     return GIF_OK;
  352.     }
  353.     else
  354.     return GIF_ERROR;
  355. }
  356.  
  357. /******************************************************************************
  358. * Put one pixel (Pixel) into GIF file.                          *
  359. ******************************************************************************/
  360. int DGifGetPixel(GifFileType *GifFile, GifPixelType Pixel)
  361. {
  362.     GifByteType *Dummy;
  363.     GifFilePrivateType *Private = (GifFilePrivateType *) GifFile -> Private;
  364.  
  365.     if (!IS_READABLE(Private)) {
  366.     /* This file was NOT open for reading: */
  367.     _GifError = D_GIF_ERR_NOT_READABLE;
  368.     return GIF_ERROR;
  369.     }
  370.  
  371. #ifdef __MSDOS__
  372.     if (--Private -> PixelCount > 0xffff0000UL)
  373. #else
  374.     if (--Private -> PixelCount > 0xffff0000)
  375. #endif /* __MSDOS__ */
  376.     {
  377.     _GifError = D_GIF_ERR_DATA_TOO_BIG;
  378.     return GIF_ERROR;
  379.     }
  380.  
  381.     if (DGifDecompressLine(GifFile, &Pixel, 1) == GIF_OK) {
  382.     if (Private -> PixelCount == 0) {
  383.         /* We probably would not be called any more, so lets clean          */
  384.         /* everything before we return: need to flush out all rest of    */
  385.         /* image until empty block (size 0) detected. We use GetCodeNext.*/
  386.         do if (DGifGetCodeNext(GifFile, &Dummy) == GIF_ERROR)
  387.         return GIF_ERROR;
  388.         while (Dummy != NULL);
  389.     }
  390.     return GIF_OK;
  391.     }
  392.     else
  393.     return GIF_ERROR;
  394. }
  395.  
  396. /******************************************************************************
  397. *   Get an extension block (see GIF manual) from gif file. This routine only  *
  398. * returns the first data block, and DGifGetExtensionNext shouldbe called      *
  399. * after this one until NULL extension is returned.                  *
  400. *   The Extension should NOT be freed by the user (not dynamically allocated).*
  401. *   Note it is assumed the Extension desc. header ('!') has been read.          *
  402. ******************************************************************************/
  403. int DGifGetExtension(GifFileType *GifFile, int *ExtCode,
  404.                             GifByteType **Extension)
  405. {
  406.     GifByteType Buf;
  407.     GifFilePrivateType *Private = (GifFilePrivateType *) GifFile -> Private;
  408.  
  409.     if (!IS_READABLE(Private)) {
  410.     /* This file was NOT open for reading: */
  411.     _GifError = D_GIF_ERR_NOT_READABLE;
  412.     return GIF_ERROR;
  413.     }
  414.  
  415.     if (fread(&Buf, 1, 1, Private -> File) != 1) {
  416.     _GifError = D_GIF_ERR_READ_FAILED;
  417.     return GIF_ERROR;
  418.     }
  419.     *ExtCode = Buf;
  420.  
  421.     return DGifGetExtensionNext(GifFile, Extension);
  422. }
  423.  
  424. /******************************************************************************
  425. *   Get a following extension block (see GIF manual) from gif file. This      *
  426. * routine sould be called until NULL Extension is returned.              *
  427. *   The Extension should NOT be freed by the user (not dynamically allocated).*
  428. ******************************************************************************/
  429. int DGifGetExtensionNext(GifFileType *GifFile, GifByteType **Extension)
  430. {
  431.     GifByteType Buf;
  432.     GifFilePrivateType *Private = (GifFilePrivateType *) GifFile -> Private;
  433.  
  434.     if (fread(&Buf, 1, 1, Private -> File) != 1) {
  435.     _GifError = D_GIF_ERR_READ_FAILED;
  436.     return GIF_ERROR;
  437.     }
  438.     if (Buf > 0) {
  439.     *Extension = Private -> Buf;           /* Use private unused buffer. */
  440.     (*Extension)[0] = Buf;  /* Pascal strings notation (pos. 0 is len.). */
  441.     if (fread(&((*Extension)[1]), 1, Buf, Private -> File) != Buf) {
  442.         _GifError = D_GIF_ERR_READ_FAILED;
  443.         return GIF_ERROR;
  444.     }
  445.     }
  446.     else
  447.     *Extension = NULL;
  448.  
  449.     return GIF_OK;
  450. }
  451.  
  452. /******************************************************************************
  453. *   This routine should be called last, to close GIF file.              *
  454. ******************************************************************************/
  455. int DGifCloseFile(GifFileType *GifFile)
  456. {
  457.     GifFilePrivateType *Private;
  458.     FILE *File;
  459.  
  460.     if (GifFile == NULL) return GIF_ERROR;
  461.  
  462.     Private = (GifFilePrivateType *) GifFile -> Private;
  463.  
  464.     if (!IS_READABLE(Private)) {
  465.     /* This file was NOT open for reading: */
  466.     _GifError = D_GIF_ERR_NOT_READABLE;
  467.     return GIF_ERROR;
  468.     }
  469.  
  470.     File = Private -> File;
  471.  
  472.     if (GifFile -> IColorMap) free((char *) GifFile -> IColorMap);
  473.     if (GifFile -> SColorMap) free((char *) GifFile -> SColorMap);
  474.     if (Private) free((char *) Private);
  475.     free(GifFile);
  476.  
  477.     if (fclose(File) != 0) {
  478.     _GifError = D_GIF_ERR_CLOSE_FAILED;
  479.     return GIF_ERROR;
  480.     }
  481.     return GIF_OK;
  482. }
  483.  
  484. /******************************************************************************
  485. *   Get 2 bytes (word) from the given file:                      *
  486. ******************************************************************************/
  487. static int DGifGetWord(FILE *File, int *Word)
  488. {
  489.     unsigned char c[2];
  490.  
  491.     if (fread(c, 1, 2, File) != 2) {
  492.     _GifError = D_GIF_ERR_READ_FAILED;
  493.     return GIF_ERROR;
  494.     }
  495.  
  496.     *Word = (((unsigned int) c[1]) << 8) + c[0];
  497.     return GIF_OK;
  498. }
  499.  
  500. /******************************************************************************
  501. *   Get the image code in compressed form. his routine can be called if the   *
  502. * information needed to be piped out as is. Obviously this is much faster     *
  503. * than decoding and encoding again. This routine should be followed by calls  *
  504. * to DGifGetCodeNext, until NULL block is returned.                  *
  505. *   The block should NOT be freed by the user (not dynamically allocated).    *
  506. ******************************************************************************/
  507. int DGifGetCode(GifFileType *GifFile, int *CodeSize, GifByteType **CodeBlock)
  508. {
  509.     GifFilePrivateType *Private = (GifFilePrivateType *) GifFile -> Private;
  510.  
  511.     if (!IS_READABLE(Private)) {
  512.     /* This file was NOT open for reading: */
  513.     _GifError = D_GIF_ERR_NOT_READABLE;
  514.     return GIF_ERROR;
  515.     }
  516.  
  517.     *CodeSize = Private -> BitsPerPixel;
  518.  
  519.     return DGifGetCodeNext(GifFile, CodeBlock);
  520. }
  521.  
  522. /******************************************************************************
  523. *   Continue to get the image code in compressed form. This routine should be *
  524. * called until NULL block is returned.                          *
  525. *   The block should NOT be freed by the user (not dynamically allocated).    *
  526. ******************************************************************************/
  527. int DGifGetCodeNext(GifFileType *GifFile, GifByteType **CodeBlock)
  528. {
  529.     GifByteType Buf;
  530.     GifFilePrivateType *Private = (GifFilePrivateType *) GifFile -> Private;
  531.  
  532.     if (fread(&Buf, 1, 1, Private -> File) != 1) {
  533.     _GifError = D_GIF_ERR_READ_FAILED;
  534.     return GIF_ERROR;
  535.     }
  536.  
  537.     if (Buf > 0) {
  538.     *CodeBlock = Private -> Buf;           /* Use private unused buffer. */
  539.     (*CodeBlock)[0] = Buf;  /* Pascal strings notation (pos. 0 is len.). */
  540.     if (fread(&((*CodeBlock)[1]), 1, Buf, Private -> File) != Buf) {
  541.         _GifError = D_GIF_ERR_READ_FAILED;
  542.         return GIF_ERROR;
  543.     }
  544.     }
  545.     else {
  546.     *CodeBlock = NULL;
  547.     Private -> Buf[0] = 0;           /* Make sure the buffer is empty! */
  548.     Private -> PixelCount = 0;   /* And local info. indicate image read. */
  549.     }
  550.  
  551.     return GIF_OK;
  552. }
  553.  
  554. /******************************************************************************
  555. *   Setup the LZ decompression for this image:                      *
  556. ******************************************************************************/
  557. static int DGifSetupDecompress(GifFileType *GifFile)
  558. {
  559.     int i, BitsPerPixel;
  560.     GifByteType CodeSize;
  561.     unsigned int *Prefix;
  562.     GifFilePrivateType *Private = (GifFilePrivateType *) GifFile -> Private;
  563.  
  564.     fread(&CodeSize, 1, 1, Private -> File);    /* Read Code size from file. */
  565.     BitsPerPixel = CodeSize;
  566.  
  567.     Private -> Buf[0] = 0;                  /* Input Buffer empty. */
  568.     Private -> BitsPerPixel = BitsPerPixel;
  569.     Private -> ClearCode = (1 << BitsPerPixel);
  570.     Private -> EOFCode = Private -> ClearCode + 1;
  571.     Private -> RunningCode = Private -> EOFCode + 1;
  572.     Private -> RunningBits = BitsPerPixel + 1;     /* Number of bits per code. */
  573.     Private -> MaxCode1 = 1 << Private -> RunningBits;     /* Max. code + 1. */
  574.     Private -> StackPtr = 0;            /* No pixels on the pixel stack. */
  575.     Private -> LastCode = NO_SUCH_CODE;
  576.     Private -> CrntShiftState = 0;    /* No information in CrntShiftDWord. */
  577.     Private -> CrntShiftDWord = 0;
  578.  
  579.     Prefix = Private -> Prefix;
  580.     for (i = 0; i <= LZ_MAX_CODE; i++) Prefix[i] = NO_SUCH_CODE;
  581.  
  582.     return GIF_OK;
  583. }
  584.  
  585. /******************************************************************************
  586. *   The LZ decompression routine:                          *
  587. *   This version decompress the given gif file into Line of length LineLen.   *
  588. *   This routine can be called few times (one per scan line, for example), in *
  589. * order the complete the whole image.                          *
  590. ******************************************************************************/
  591. static int DGifDecompressLine(GifFileType *GifFile, GifPixelType *Line,
  592.                                 int LineLen)
  593. {
  594.     int i = 0, j, CrntCode, EOFCode, ClearCode, CrntPrefix, LastCode, StackPtr;
  595.     GifByteType *Stack, *Suffix;
  596.     unsigned int *Prefix;
  597.     GifFilePrivateType *Private = (GifFilePrivateType *) GifFile -> Private;
  598.  
  599.     StackPtr = Private -> StackPtr;
  600.     Prefix = Private -> Prefix;
  601.     Suffix = Private -> Suffix;
  602.     Stack = Private -> Stack;
  603.     EOFCode = Private -> EOFCode;
  604.     ClearCode = Private -> ClearCode;
  605.     LastCode = Private -> LastCode;
  606.  
  607.     if (StackPtr != 0) {
  608.     /* Let pop the stack off before continueing to read the gif file: */
  609.     while (StackPtr != 0 && i < LineLen) Line[i++] = Stack[--StackPtr];
  610.     }
  611.  
  612.     while (i < LineLen) {                /* Decode LineLen items. */
  613.     if (DGifDecompressInput(Private, &CrntCode) == GIF_ERROR)
  614.             return GIF_ERROR;
  615.  
  616.     if (CrntCode == EOFCode) {
  617.         /* Note however that usually we will not be here as we will stop */
  618.         /* decoding as soon as we got all the pixel, or EOF code will    */
  619.         /* not be read at all, and DGifGetLine/Pixel clean everything.   */
  620.         if (i != LineLen - 1 || Private -> PixelCount != 0) {
  621.         _GifError = D_GIF_ERR_EOF_TOO_SOON;
  622.         return GIF_ERROR;
  623.         }
  624.         i++;
  625.     }
  626.     else if (CrntCode == ClearCode) {
  627.         /* We need to start over again: */
  628.         for (j = 0; j <= LZ_MAX_CODE; j++) Prefix[j] = NO_SUCH_CODE;
  629.         Private -> RunningCode = Private -> EOFCode + 1;
  630.         Private -> RunningBits = Private -> BitsPerPixel + 1;
  631.         Private -> MaxCode1 = 1 << Private -> RunningBits;
  632.         LastCode = Private -> LastCode = NO_SUCH_CODE;
  633.     }
  634.     else {
  635.         /* Its regular code - if in pixel range simply add it to output  */
  636.         /* stream, otherwise trace to codes linked list until the prefix */
  637.         /* is in pixel range:                         */
  638.         if (CrntCode < ClearCode) {
  639.         /* This is simple - its pixel scalar, so add it to output:   */
  640.         Line[i++] = CrntCode;
  641.         }
  642.         else {
  643.         /* Its a code to needed to be traced: trace the linked list  */
  644.         /* until the prefix is a pixel, while pushing the suffix     */
  645.         /* pixels on our stack. If we done, pop the stack in reverse */
  646.         /* (thats what stack is good for!) order to output.         */
  647.         if (Prefix[CrntCode] == NO_SUCH_CODE) {
  648.             /* Only allowed if CrntCode is exactly the running code: */
  649.             /* In that case CrntCode = XXXCode, CrntCode or the         */
  650.             /* prefix code is last code and the suffix char is         */
  651.             /* exactly the prefix of last code!                 */
  652.             if (CrntCode == Private -> RunningCode - 2) {
  653.             CrntPrefix = LastCode;
  654.             Suffix[Private -> RunningCode - 2] =
  655.             Stack[StackPtr++] = DGifGetPrefixChar(Prefix,
  656.                             LastCode, ClearCode);
  657.             }
  658.             else {
  659.             _GifError = D_GIF_ERR_IMAGE_DEFECT;
  660.             return GIF_ERROR;
  661.             }
  662.         }
  663.         else
  664.             CrntPrefix = CrntCode;
  665.  
  666.         /* Now (if image is O.K.) we should not get an NO_SUCH_CODE  */
  667.         /* During the trace. As we might loop forever, in case of    */
  668.         /* defective image, we count the number of loops we trace    */
  669.         /* and stop if we got LZ_MAX_CODE. obviously we can not      */
  670.         /* loop more than that.                         */
  671.         j = 0;
  672.         while (j++ <= LZ_MAX_CODE &&
  673.                CrntPrefix > ClearCode &&
  674.                CrntPrefix <= LZ_MAX_CODE) {
  675.             Stack[StackPtr++] = Suffix[CrntPrefix];
  676.             CrntPrefix = Prefix[CrntPrefix];
  677.         }
  678.         if (j >= LZ_MAX_CODE || CrntPrefix > LZ_MAX_CODE) {
  679.             _GifError = D_GIF_ERR_IMAGE_DEFECT;
  680.             return GIF_ERROR;
  681.         }
  682.         /* Push the last character on stack: */
  683.         Stack[StackPtr++] = CrntPrefix;
  684.  
  685.         /* Now lets pop all the stack into output: */
  686.         while (StackPtr != 0 && i < LineLen)
  687.             Line[i++] = Stack[--StackPtr];
  688.         }
  689.         if (LastCode != NO_SUCH_CODE) {
  690.         Prefix[Private -> RunningCode - 2] = LastCode;
  691.  
  692.         if (CrntCode == Private -> RunningCode - 2) {
  693.             /* Only allowed if CrntCode is exactly the running code: */
  694.             /* In that case CrntCode = XXXCode, CrntCode or the         */
  695.             /* prefix code is last code and the suffix char is         */
  696.             /* exactly the prefix of last code!                 */
  697.             Suffix[Private -> RunningCode - 2] =
  698.             DGifGetPrefixChar(Prefix, LastCode, ClearCode);
  699.         }
  700.         else {
  701.             Suffix[Private -> RunningCode - 2] =
  702.             DGifGetPrefixChar(Prefix, CrntCode, ClearCode);
  703.         }
  704.         }
  705.         LastCode = CrntCode;
  706.     }
  707.     }
  708.  
  709.     Private -> LastCode = LastCode;
  710.     Private -> StackPtr = StackPtr;
  711.  
  712.     return GIF_OK;
  713. }
  714.  
  715. /******************************************************************************
  716. * Routine to trace the Prefixes linked list until we get a prefix which is    *
  717. * not code, but a pixel value (less than ClearCode). Returns that pixel value.*
  718. * If image is defective, we might loop here forever, so we limit the loops to *
  719. * the maximum possible if image O.k. - LZ_MAX_CODE times.              *
  720. ******************************************************************************/
  721. static int DGifGetPrefixChar(unsigned int *Prefix, int Code, int ClearCode)
  722. {
  723.     int i = 0;
  724.  
  725.     while (Code > ClearCode && i++ <= LZ_MAX_CODE) Code = Prefix[Code];
  726.     return Code;
  727. }
  728.  
  729. /******************************************************************************
  730. *   Interface for accessing the LZ codes directly. Set Code to the real code  *
  731. * (12bits), or to -1 if EOF code is returned.                      *
  732. ******************************************************************************/
  733. int DGifGetLZCodes(GifFileType *GifFile, int *Code)
  734. {
  735.     GifByteType *CodeBlock;
  736.     GifFilePrivateType *Private = (GifFilePrivateType *) GifFile -> Private;
  737.  
  738.     if (!IS_READABLE(Private)) {
  739.     /* This file was NOT open for reading: */
  740.     _GifError = D_GIF_ERR_NOT_READABLE;
  741.     return GIF_ERROR;
  742.     }
  743.  
  744.     if (DGifDecompressInput(Private, Code) == GIF_ERROR)
  745.     return GIF_ERROR;
  746.  
  747.     if (*Code == Private -> EOFCode) {
  748.     /* Skip rest of codes (hopefully only NULL terminating block): */
  749.     do if (DGifGetCodeNext(GifFile, &CodeBlock) == GIF_ERROR)
  750.             return GIF_ERROR;
  751.     while (CodeBlock != NULL);
  752.  
  753.     *Code = -1;
  754.     }
  755.     else if (*Code == Private -> ClearCode) {
  756.     /* We need to start over again: */
  757.     Private -> RunningCode = Private -> EOFCode + 1;
  758.     Private -> RunningBits = Private -> BitsPerPixel + 1;
  759.     Private -> MaxCode1 = 1 << Private -> RunningBits;
  760.     }
  761.  
  762.     return GIF_OK;
  763. }
  764.  
  765. /******************************************************************************
  766. *   The LZ decompression input routine:                          *
  767. *   This routine is responsable for the decompression of the bit stream from  *
  768. * 8 bits (bytes) packets, into the real codes.                      *
  769. *   Returns GIF_OK if read succesfully.                          *
  770. ******************************************************************************/
  771. static int DGifDecompressInput(GifFilePrivateType *Private, int *Code)
  772. {
  773.     GifByteType NextByte;
  774.     static unsigned int CodeMasks[] = {
  775.     0x0000, 0x0001, 0x0003, 0x0007,
  776.     0x000f, 0x001f, 0x003f, 0x007f,
  777.     0x00ff, 0x01ff, 0x03ff, 0x07ff,
  778.     0x0fff
  779.     };
  780.  
  781.     while (Private -> CrntShiftState < Private -> RunningBits) {
  782.     /* Needs to get more bytes from input stream for next code: */
  783.     if (DGifBufferedInput(Private -> File, Private -> Buf, &NextByte)
  784.         == GIF_ERROR) {
  785.         return GIF_ERROR;
  786.     }
  787.     Private -> CrntShiftDWord |=
  788.         ((unsigned long) NextByte) << Private -> CrntShiftState;
  789.     Private -> CrntShiftState += 8;
  790.     }
  791.     *Code = Private -> CrntShiftDWord & CodeMasks[Private -> RunningBits];
  792.  
  793.     Private -> CrntShiftDWord >>= Private -> RunningBits;
  794.     Private -> CrntShiftState -= Private -> RunningBits;
  795.  
  796.     /* If code cannt fit into RunningBits bits, must raise its size. Note */
  797.     /* however that codes above 4095 are used for special signaling.      */
  798.     if (++Private -> RunningCode > Private -> MaxCode1 &&
  799.     Private -> RunningBits < LZ_BITS) {
  800.     Private -> MaxCode1 <<= 1;
  801.     Private -> RunningBits++;
  802.     }
  803.     return GIF_OK;
  804. }
  805.  
  806. /******************************************************************************
  807. *   This routines read one gif data block at a time and buffers it internally *
  808. * so that the decompression routine could access it.                  *
  809. *   The routine returns the next byte from its internal buffer (or read next  *
  810. * block in if buffer empty) and returns GIF_OK if succesful.              *
  811. ******************************************************************************/
  812. static int DGifBufferedInput(FILE *File, GifByteType *Buf,
  813.                               GifByteType *NextByte)
  814. {
  815.     if (Buf[0] == 0) {
  816.     /* Needs to read the next buffer - this one is empty: */
  817.     if (fread(Buf, 1, 1, File) != 1)
  818.     {
  819.         _GifError = D_GIF_ERR_READ_FAILED;
  820.         return GIF_ERROR;
  821.     }
  822.     if (fread(&Buf[1], 1, Buf[0], File) != Buf[0])
  823.     {
  824.         _GifError = D_GIF_ERR_READ_FAILED;
  825.         return GIF_ERROR;
  826.     }
  827.     *NextByte = Buf[1];
  828.     Buf[1] = 2;       /* We use now the second place as last char read! */
  829.     Buf[0]--;
  830.     }
  831.     else {
  832.     *NextByte = Buf[Buf[1]++];
  833.     Buf[0]--;
  834.     }
  835.  
  836.     return GIF_OK;
  837. }
  838.